extends Area2D
class_name GrabRigidBody2DComponent

signal grabed
signal placed

@export var node2d_whitelist:Array[RigidBody2D]
var grabed_rigidbody2d:RigidBody2D

@export var spring_stiffness: float = 100.0
@export var damping: float = 5.0

func _ready() -> void:
	body_entered.connect(grab)
	body_exited.connect(place)

func _physics_process(_delta: float) -> void:
	if Input.is_action_just_pressed("grab"):
		monitoring = true
	if !grabed_rigidbody2d:
		return
	var target_pos = global_position
	var current_pos = grabed_rigidbody2d.global_position
	var velocity = grabed_rigidbody2d.linear_velocity
	
	var spring_force = (target_pos - current_pos) * spring_stiffness
	var damping_force = -velocity * damping
	
	grabed_rigidbody2d.apply_central_force(spring_force + damping_force)
	if Input.is_action_just_pressed("throw"):
		throw()
		stop_grab()

func throw():
	var dir = get_global_mouse_position() - global_position
	grabed_rigidbody2d.apply_central_impulse(dir / 2)

func grab(body:Node2D):
	if body in node2d_whitelist:
		return
	if body is RigidBody2D:
		grabed_rigidbody2d = body
		grabed.emit()

func stop_grab():
	node2d_whitelist.append(grabed_rigidbody2d)
	grabed_rigidbody2d = null
	monitoring = true

func place(placed_node:Node):
	if placed_node in node2d_whitelist:
		node2d_whitelist.erase(placed_node)
		set_deferred("monitoring",false)
		placed.emit()
